package com.vito.base.authoriza.action;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.POIXMLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.dubbo.config.annotation.Reference;
import com.vito.base.authoriza.cache.SessionMap;
import com.vito.base.authoriza.model.DeptModel;
import com.vito.base.authoriza.model.ExcelModel;
import com.vito.base.authoriza.service.CreateId;
import com.vito.base.authoriza.service.ExcelService;
import com.vito.base.exception.ParamErrorException;
import com.vito.base.factory.IDFactory;
import com.vito.base.model.DataGrid;
import com.vito.base.model.ResMsg;
import com.vito.base.model.Result;
import com.vito.base.util.ExcelHelper;
import com.vito.base.util.GenExcelXmlUtil;
import com.vito.base.util.StringUtil;


@Controller("excelImportAction")
@RequestMapping("base/authoriza/excel")
public class ExcelAction extends BaseAction{
	private static final Logger log = LoggerFactory.getLogger(UserAction.class);
	

	@Reference
	private ExcelService excelServiceImpl;
	@Reference
	private CreateId createId;
	
	@ResponseBody
	@RequestMapping(value="importByBase64",method=RequestMethod.POST)
	public Result uploadByBase64(String file,String type){
		Result res = new Result();
		File f = null;
		FileOutputStream fos =null;
		try{
			if("xlsx".equals(type)||"xls".equals(type)){
				byte[] b = StringUtil.decode(file);
				f = new File(createId.getId("IMPORT")+"."+type);
				fos = new FileOutputStream(f);
				fos.write(b);
				fos.flush();
				fos.close();
				
				return saveImport(f.getAbsolutePath(),null);
			}else{
				res.setCode(Result.CODE_PARA_ERROR);
				res.setMsg("文件类型错误");
			}
		}catch(Exception ex){
			ex.printStackTrace();
			res.setCode(Result.CODE_ERROR);
			res.setMsg(ex.getMessage());
		}finally {
			try {
				if(fos!=null)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if(f!=null&& f.exists())
					f.delete();
			}
		}
		
		return res;
	}
	
	@ResponseBody
	@RequestMapping(value="import",method=RequestMethod.POST)
	public Result uploadByForm(@RequestParam MultipartFile file,String serid){
		Result res = new Result();
		File f = null;
		FileOutputStream fos =null;
		try{
//			f = new File((createId.getId("IMPORT")+"."+StringUtil.getExt(file.getOriginalFilename())));
			f = new File((IDFactory.getIDFactory().getIdInc()+"."+StringUtil.getExt(file.getOriginalFilename())));
			fos = new FileOutputStream(f);
			fos.write(file.getBytes());
			fos.flush();
			fos.close();
			log.debug("first--titleStart:" + titleStart);
			if(f.getName().endsWith("xls")||f.getName().endsWith("xlsx")){
				log.debug("f.getPath():" + f.getPath());
				return saveImport(f.getPath(),serid);
			}else{
				res.setCode(Result.CODE_PARA_ERROR);
				res.setMsg("文件类型错误");
			}
		}catch(Exception ex){
			ex.printStackTrace();
			res.setCode(Result.CODE_ERROR);
			res.setMsg(ex.getMessage());
		}finally {
			try{
				if(fos!=null){
					fos.close();
				}
			}catch(Exception e){
				
			}finally {
				if(f!=null && f.exists())
					f.delete();
			}
		}
		return res;
	}
	
	private Integer titleStart = 3,comtentStart=4,maxrow = 5000;
	private List<Map<String,Object>> rules = null;
	
	private void initParam(Map<String, Object> queryRuler){
		this.rules =  (List<Map<String, Object>>) queryRuler.get("rules");
		log.debug("initParam--before--titleStart:" + titleStart);
		if(queryRuler.containsKey("titlestartrow")){
			try {
				this.titleStart = Integer.valueOf(queryRuler.get("titlestartrow").toString());
				log.debug("initParam--after--titleStart:" + titleStart);
			} catch (Exception e) {
			}
		}
		if(queryRuler.containsKey("contentstartrow")){
			try {
				this.comtentStart = Integer.valueOf(queryRuler.get("contentstartrow").toString());
			} catch (Exception e) {
			}
		}
		if(queryRuler.containsKey("maxrowcount")){
			try {
				this.maxrow = Integer.valueOf(queryRuler.get("maxrowcount").toString());
			} catch (Exception e) {
			}
		}
	}
	
	private List<Object> importValidate(String path) throws IOException, ParamErrorException{
		ExcelHelper eh = new ExcelHelper();
		List<Object> readList = eh.readList(path);
		String decrypt = "";
		try {
			decrypt = GenExcelXmlUtil.decrypt(eh.getDescription());
		} catch (Exception e) {
		 	throw new ParamErrorException("导入校验信息解码失败！");
		}
		log.debug("decrypt:" + decrypt);
		Map<String, Object> queryRuler = excelServiceImpl.queryRuler(decrypt);
		if(queryRuler!=null){
			initParam(queryRuler);
		}else{
			throw new ParamErrorException("导入数据格式有误，导入失败");
		}
		//超出最大行数
		if(readList==null||readList.size()<=titleStart){
			throw new ParamErrorException("导入数据格式有误或为空，导入失败");
		}else if(readList.size()>maxrow){
			throw new ParamErrorException("导入数据行数超过"+maxrow+"行，导入失败");
		}
		//指定规则  
		if(rules!=null){
			String regex = null,title=null,value=null;
			int index = 0;
			Pattern p = null;
			List<Object> list = null;
			Matcher m = null;
			Map<String, Object> ruleitem = null;
			for(int listindex = 0;listindex<rules.size();listindex++){
				ruleitem = rules.get(listindex);
				//忽略 么有orderby的列
				if(!ruleitem.containsKey("orderby"))
					index = listindex;
				else if("".equals(ruleitem.get("orderby")))
					index = listindex;
				else if((index = (new BigDecimal(Double.parseDouble(ruleitem.get("orderby")+""))).intValue())<0)
					index = listindex;
					
//				if(ruleitem.containsKey("regex")&&(regex = (String) ruleitem.get("regex"))!=null){
//					p = Pattern.compile(regex);
//					if(regex!=null&&!"".equals(regex)){
//						for(int i=comtentStart-1;i<readList.size();i++){
//							list = (List<Object>) readList.get(i);
//							if(list.size()>=index){
//								value = list.get(index).toString();
//								m = p.matcher(value);
//								if(!m.matches()){
//									throw new ParamErrorException(new StringBuilder("列表中第").append(i+1)
//											.append("行，第").append(index+1)
//											.append("列，不满足数据规则！实际值为：").append(value)
//											.append("，规则：").append(regex).toString());
//									
//								}
//							}
//						}
//					}
//				}
				if(ruleitem.containsKey("titlename")){
					title = (String) ruleitem.get("titlename");
					log.debug("last--titleStart:" + titleStart);
					List<Object> titles = (List<Object>) readList.get(titleStart-1);
					log.debug("titles:" + titles.toString());
					if(titles!=null&&titles.size()>=index){
						if(!title.equals(titles.get(index))){
							throw new ParamErrorException(new StringBuilder("列表中第").append(titleStart)
									.append("行，第").append(index+1)
									.append("列，不是：").append(title).toString());
						}
					}else{
						throw new ParamErrorException(new StringBuilder("列表中第").append(titleStart)
								.append("行，第").append(index+1)
								.append("列，应该是：").append(title)
								.append("，程序检查到空值").toString());
					}
				}
			}
		}
		return readList;
	}
	private List<Object> importValidateData(List<Object> readList) throws Exception{
		List<Object> list = null;
		List<Object> errorList = new ArrayList<Object>();
		String value=null;
		//便利校验数据是否为空
		for(int i=comtentStart-1;i<readList.size();i++){
			list = (List<Object>) readList.get(i);
			if(list!=null&&list.size()>0){
				int emportNum = 0;
				boolean flag = true;
				for (int j = 0; j < list.size(); j++) {
					value = (String) list.get(j);
					if(rules!=null){
						if(j==rules.size()){
							break;
						}
						Map<String, Object> ruleitem = rules.get(j);
						if(ruleitem!=null){
							if(ruleitem.containsKey("nullable") && "1".equals(ruleitem.get("nullable")) && StringUtil.isEmpty(value)){//不能为空
								list.remove(j);
								list.add(j,"@3@"+value);
								if(flag){
									flag = false;
								}
							}else if(ruleitem.containsKey("regex")){
								//使用正则表达式校验数值
								if(!valdataReg((String)ruleitem.get("regex"),value)){
									list.remove(j);
									list.add(j,"@1@"+value);
									if(flag){
										flag = false;
									}
								}
							}
						}
//						if(ruleitem!=null&&ruleitem.containsKey("regex")){
//							//使用正则表达式校验数值
//							if(!valdataReg((String)ruleitem.get("regex"),value,(String)ruleitem.get("nullable"))){
//								list.remove(j);
//								list.add(j,"@1@"+value);
//								if(flag){
//									flag = false;
//								}
//							}
//						}
					}
					if(StringUtil.isEmpty(value)){
						emportNum++;
					}
				}
				if(emportNum==list.size()){
					list.remove(0);
					list.add(0,"@2@");
					list.add(0,i+1);
					errorList.add(list);
				}else if(!flag){
					list.add(0,i+1);
					errorList.add(list);
				}
			}else{
				list= (List<Object>) readList.get(titleStart-1);
				list.remove(0);
				list.add(0,"@2@");
				for (int j = 1; j < list.size(); j++) {
					list.remove(j);
					list.add(j, "");
				}
				list.add(0,i+1);
				errorList.add(list);
			}
			
				
		}
		return errorList;
	}
	private boolean valdataReg(String regex,String value){
		Pattern p = null;
		Matcher m = null;
		boolean flag = true;
		if(regex !=null&&(!StringUtil.isEmpty(value))){
			p = Pattern.compile(regex);
			if(regex!=null&&!"".equals(regex)){
				m = p.matcher(value);
				if(!m.matches()){
					flag = false;
				}
				
			}
		}
		return flag;
	}
	public static void main(String[] args) {
		try {
			System.out.println(new ExcelAction().importValidate("C:/Users/tianjing/Downloads/车位信息 (3).xls"));
		} catch (IOException | ParamErrorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@RequestMapping("importByURI")
	@ResponseBody
	public Result saveImport(String path,String serid){
		Result res = new Result();
		try{
			//进行表头校验
			List<Object> list = importValidate(path);
			List<Object> listError = importValidateData(list);
			//进行数值校验
			if(listError==null||listError.size()==0){
				res.setData(excelServiceImpl.saveImport(list,SessionMap.getObj().getUserId()));
				res.setCode(Result.CODE_OK);
			}else{
				res.setData(excelServiceImpl.saveErrorImport(listError,SessionMap.getObj().getUserId(),serid));
				res.setCode(Result.CODE_NEED_JUMP);
			}
		}catch(ParamErrorException e){
			res.setMsg(e.getMessage());
			res.setCode(Result.CODE_ERROR);
		}catch (FileNotFoundException e) {
			res.setMsg("请重新上传需要导入的文件！");
			res.setCode(Result.CODE_ERROR);
		}catch(POIXMLException ex){
			res.setMsg("不支持的excel文件！");
			res.setCode(Result.CODE_PARA_ERROR);
		}catch(Exception ex){
			log.error(ResMsg.EXECERR,ex);
			res.setMsg(ResMsg.EXECERR);
			res.setCode(Result.CODE_ERROR);
		}finally {
			File file = new File(path);
			if(file.exists()){
				file.delete();
			}
		}
		return res ;
	}
	@RequestMapping("getErrorByPage")
	@ResponseBody
	public Result queryByPage(ExcelModel model) {
		Result res = new Result();
		try{
			DataGrid<ExcelModel> page = excelServiceImpl.queryErrorByPage(model);
			if(page.getTotal()!=0){
				res.setCode(Result.CODE_OK);
				res.setData(page);
			}else{
				res.setCode(Result.CODE_NO_DATA);
				res.setMsg("暂无数据");
			}
		}catch(Exception ex){
			log.error("查询异常",ex);
			res.setCode(Result.CODE_ERROR);
			res.setMsg("查询异常");
		}
		return res ;
	}
}


